<!-- ? 模块 -->
<template>
    <el-form ref="formRef" :model="modelValue" label-width="auto" style="max-width: 600px" :rules="rules">
        <el-form-item v-for="item in items" :key="item.key" :label="item.label" :prop="item.key">
            <slot :name="item.key">
                <component :is="getComponent(item.type)" v-bind="getPros(item)" v-model="modelValue[item.key]">
                    <template v-if="item.type === 'select'">
                        <el-option v-for="option in item.props.options" :key="option.value" :label="option.label"
                            :value="option.value"></el-option>
                    </template>
                </component>
            </slot>
        </el-form-item>
    </el-form>
</template>

<script setup lang="ts">
import type { FormInstance } from 'element-plus';
import { computed, ref, useTemplateRef } from 'vue';
import { omit } from 'lodash-es';
const props = defineProps(['formData', 'rules', 'formItems']);

const formInstance = useTemplateRef<FormInstance>('formRef');
const modelValue = defineModel();

const componentMap = {
    input: 'el-input',
    number: 'el-input-number',
    select: 'el-select',
};

const rootProps = ['label', 'key', 'type'];

const items = computed(() => props.formItems.filter((item: any) => !item.hidden));

function getPros(item: any) {
    if (item.props) return item.props;
    return omit(item, rootProps);
}

function getComponent(item) {
    const type = item;
    if (type && typeof type !== 'string') {
        return type;
    }
    return componentMap[type || 'input'];
}

defineExpose({
    validate(...args: Parameters<FormInstance['validate']>) {
        return formInstance.value?.validate(...args);
    },
    resetFields(...args: Parameters<FormInstance['resetFields']>) {
        return formInstance.value?.resetFields(...args);
    },
    clearValidate(...args: Parameters<FormInstance['clearValidate']>) {
        return formInstance.value?.clearValidate(...args);
    }
});
</script>

<style lang="scss" scoped></style>
